package modules.java8.lambda1;

import modules.entities.User;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.PrintStream;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * Java8 新特性
 *    四大函数式接口：
 *          函数式接口：只有一个方法的接口
 *    方法引用：
 *      //方法引用    ClassName::method
 *      //构造器引用: ClassName::new
 *      //数组引用：  Type::new;
 *
 * @author shengren.yan
 * @create 2021-03-15
 */
@SpringBootTest
public class Lambda1 {

    /**
     *
     * java内置四大函数式接口
     *
     * Consumer<T> :消费型接口     只有输入，没有返回值
     * 			void accept(T t);
     *
     * Supplier<T> :供给型接口     没有参数，只有返回值
     * 			T get();
     *
     * Function<T,R> :函数型接口   有一个输入参数 参数输出
     * 			R apply(T t);
     *
     * Predicate<T> :断言型接口    有一个输入参数 返回只能是布尔值
     * 			boolean test(T t);
     *
     */

    //方法引用
    @Test
    public void test1(){
        // 对象的引用 :: 实例方法名
        User emp = new User(101, "张三");
        Supplier<String> sup = () -> emp.getUsername();
        System.out.println(sup.get());

        Supplier<String> sup2 = emp::getUsername;
        System.out.println(sup2.get());

        // 类名 :: 静态方法名
        Comparator<Integer> comparator1 = (x, y) -> Integer.compare(x, y);
        Comparator<Integer> comparator2 = Integer::compare;

        // 类名 :: 实例方法名
        BiPredicate<String, String> bp = (x, y) -> x.equals(y);
        System.out.println(bp.test("abcde", "abcde"));
        BiPredicate<String, String> bp2 = String::equals;
        System.out.println(bp2.test("abc", "abc"));

        // 构造器引用
        // 构造器的参数列表，需要与函数式接口中参数列表保持一致 (就是函数签名一致)
        // 类名 :: new
        Supplier<User> user = () -> new User();
        System.out.println(user.get());
        Supplier<User> user2 = User::new;
        System.out.println(user2.get());

        // 数组引用
        // 类型[] :: new
        Function<Integer, String[]> fun = (args) -> new String[args];
        String[] strs = fun.apply(10);
        System.out.println(strs.length);

        Function<Integer,String[]> fun1 = String[]::new;
        strs = fun1.apply(20);
        System.out.println(strs.length);

    }

}
